package main

import (
    "fmt"
)

/***
CHKSUM 数据格式
CHKSUM的计算是除SOI、EOI和CHKSUM外，其他字符按ASCII码值累加求和，所得结果模65536余数取反加1。
例：
收到或发送的字符序列是：“~20014043E00200FD3BCR”（“~”为SOI，“CR”为EOI），则最后五个字符“FD3BCR”
中的FD3B是CHKSUM，计算方法是：
‘2’+‘0’+‘0’+ … +‘E’+‘0’+‘0’+‘2’+‘0’+‘0’
= 32H + 30H + 30H + … + 45H + 30H + 30H + 32H + 30H + 30H
= 02C5H
其中‘2’表示数字2的ASCII码值32H，‘E’表示E的ASCII码值45H 。02C5H模65536余数是02C5H，02C5H取反加1就是FD3BH。
*/

// calculateCHKSUM 计算给定字符串的CHKSUM
// 输入的字符串应该排除SOI、EOI和CHKSUM本身
func calculateCHKSUM(input string) string {
    var sum uint16
    for _, char := range input {
        sum += uint16(char)
    }
    // 取模65536的余数（这一步实际上在uint16上自动完成）
    // 取反加1
    checksum := ^sum + 1
    // 转换为大写十六进制字符串，占4位
    return fmt.Sprintf("%04X", checksum)
}

func main() {
    // 示例字符串，排除了SOI、EOI和CHKSUM本身
    input := "20014043E00200"
    // 计算CHKSUM
    checksum := calculateCHKSUM(input)
    fmt.Println("计算CHKSUM  :", checksum)

    // 验证示例
    example := "~20014043E00200FD3BCR"
    // 提取除SOI、EOI外的字符串用于验证


    content := example[1 : len(example)-6]
    // 实际CHKSUM值，从输入字符串中提取
	fmt.Println("原始数据 :", example)
	fmt.Println("提取除SOI、EOI外的字符串用于验证 content:", content)

   actualChecksum := example[len(example)-6 : len(example)-2]
    // 计算
    calculatedChecksum := calculateCHKSUM(content)
    fmt.Println("原数据  尾部校验值:", actualChecksum)
    fmt.Println("原始数据载荷计算值:", calculatedChecksum)

    // 验证计算的CHKSUM是否与给出的相同
    if actualChecksum == calculatedChecksum {
        fmt.Println("计算正确.")
    } else {
        fmt.Println("计算不匹配. Expected:", actualChecksum, "Got:", calculatedChecksum)
    }
}
